require("./CourseVideoEdit.scss")

require("../../both/base")

class CourseVideoEdit extends React.Component {
    constructor(props){
        super(props)

        const {course,init,courseId,setCourse} = props

        init(courseId)

        this.state = {
            videoExist : true,
            videoLocation : course.location,

            progress : 0,       // 上传进度..
            filename : "",
            status : "",
            file : {}       // file对象
        }
    }

    //得到视频合并进度
    getVideoMergeProgress(guid,cb,st){
        return fetch(`${location.protocol}//${location.hostname}:${location.port}/mergeStatus`,{
            method: 'POST',
            body: JSON.stringify({guid : guid}),
            headers: { 'Content-Type': 'application/json' }
        })
            .then(res => res.json())
            .then(json => {
                cb && cb(json.progress,null)
                return json.progress
            }).catch((err) => {
                cb && cb(null,err)
                clearInterval(st)
            })
    }

    // 包裹函数
    getVideoMergeProgressWrap(guid,callback){
        const getVideoMergeProgress = this.getVideoMergeProgress.bind(this)
        // 1s 一次
        var st = setInterval(() => {
            getVideoMergeProgress(guid,callback,st)
                .then(progress => {
                    if(progress == 100){
                        console.log("merge over")
                        clearInterval(st)
                    }
                })
        },1000)
    }

    componentDidMount(){
        var self = this
        const {course,setCourse,delCourse} = self.props
        const getVideoMergeProgressWrap = self.getVideoMergeProgressWrap.bind(self)

        // player init
        var player = self.player = jwplayer("player").setup({
            "autostart": true,
            "controls": true,
            "displaydescription": true,
            "file": self.state.videoLocation,
            // "image": "/upload/example.jpg",
            "stretching": "uniform",
            "width" : "100%",
            "height" : 800 * 9 / 16,
            "skin": {
                "name": "six"
            },
            "key" : "c3imBsxqNKqKLN38V5P5N2vrpWIgFWH0FodRLw==",
            "flashplayer": "/p_dist/jwplayer/jwplayer.flash.swf"
        })

        player.on('error',(msg) => {
            self.setState({         // setState之后componentDidMount不会重复执行
                videoExist : false
            })
        })

        player.on('play', () => {
            self.setState({         // setState之后componentDidMount不会重复执行
                videoExist : true
            })
        })

        // uploader init
        var GUID = WebUploader.Base.guid()      // 上传标识
        var uploader = self.uploader = WebUploader.create({
            auto: false,
            pick: '#filePicker',
            server: `${location.protocol}//${location.hostname}:${location.port}/postFile`,
            accept: {
                title: 'Videos',
                extensions: 'mp4',
                mimeTypes: 'video/mp4'
            },
            chunked : true,
            threads : 1,
            fileNumLimit : 1,
            chunkSize : 1024 * 1024 * 1,       // 10M
            fileSizeLimit : 5 * 1024 * 1024 * 1024,     // 5G
            formData : {
                guid : GUID
            },
            prepareNextFile: true
        })

        uploader.on('uploadStart', () => {
            GUID = WebUploader.Base.guid()
        })

        uploader.on('uploadSuccess', function( file, re) {
            toastr.success("视频上传成功")
            uploader.reset()

            self.setState({
                status : "上传成功"
            })

            if(re.chunked){
                fetch(`${location.protocol}//${location.hostname}:${location.port}/merge`, {
                    method: 'POST',
                    body: JSON.stringify({guid : re.guid,filename:file.name}),
                    headers: { 'Content-Type': 'application/json' }
                })
                    .then(res => res.json())
                    .then(json => {
                        console.log(json)
                        // delete old file
                        fetch(`${location.protocol}//${location.hostname}:${location.port}/cleanVideo`,{
                            method : 'POST',
                            body : JSON.stringify({
                                videoLocation : self.state.videoLocation
                            }),
                            headers: { 'Content-Type': 'application/json' }
                        })

                        // set new course
                        setCourse({
                            title : course.title,
                            cover : course.cover,
                            description : course.description,
                            major : course.major,
                            id : course.id,
                            location : json.url
                        })

                        self.setState({
                            videoLocation : json.url,
                            status : "合并中"
                        })

                        getVideoMergeProgressWrap(re.guid,(progress,err) => {

                            self.setState({
                                progress : Math.round(progress * 100) / 100
                            })
                            document.getElementById("merge_process").style.right = (200 - progress / 100 * 200) + "px"

                            if(err){
                                console.error(err)
                                toastr.error("后台合并文件出错")
                            }
                            if(progress == 100){

                                self.setState({
                                    status : "上传成功"
                                })

                                player.load([{
                                    "file": json.url,
                                    "title": course.title
                                }])
                            }
                        })

                    }).catch((err) => {
                        toastr.error("文件后台合并出错，上传失败")
                })
            }else{

                setCourse({
                    title : course.title,
                    cover : course.cover,
                    description : course.description,
                    major : course.major,
                    id : course.id,
                    location : re.url
                })

                self.setState({
                    videoLocation : re.url
                })

                player.load([{
                    "file": re.url,
                    "title": course.title
                }])

            }
        })

        uploader.on("fileQueued",function (file){
            self.setState({
                filename : file.name,
                progress : 0,
                status : "队列中",
                file : file
            })
            document.getElementById("process").style.right = 200 + "px" // bar scroll
            document.getElementById("merge_process").style.right = 200 + "px"
        })

        uploader.on("uploadProgress",function (file,percentage) {
            var percent = Math.round(percentage * 1000) / 10
            self.setState({
                progress : percent,
                status : "上传中"
            })
            document.getElementById("process").style.right = (200 - percent / 100 * 200) + "px" // bar scroll
        })

        uploader.on( 'uploadError', function( file ) {
            toastr.error("视频上传失败")
            self.setState({
                progress : 0,
                status : "上传失败"
            })
            uploader.reset()
        })

        uploader.on("uploadBeforeSend", function(block){
            var task = WebUploader.Deferred()

            return fetch(`${location.protocol}//${location.hostname}:${location.port}/checkChunk`, {
                method: 'POST',
                body: JSON.stringify({guid : GUID,filename : block.file.name,chunk : block.chunk}),
                timeout : 1000,
                headers: { 'Content-Type': 'application/json' }
            })
                .then(res => res.json())
                .then(json => {
                    if(json.is_exist){
                        task.reject()
                    }else{
                        task.resolve()
                    }
                }).catch((err) => {
                    console.error(err)
                    task.resolve()
            })
        })
    }

    componentWillReceiveProps(nextProps){
        const {course} = nextProps

        var isEmptyObj = true
        for(var k in course){
            isEmptyObj = false
        }
        if(isEmptyObj){
            return
        }

        this.setState({
            videoExist : true,
            videoLocation : course.location
        })
    }

    stopUpload(){
        // console.log("stop upload")
        this.uploader.stop(true)
        this.setState({
            status : "暂停中"
        })
    }

    startUpload(){
        this.uploader.upload()
        this.setState({
            status : "上传中"
        })
    }

    deleteFile(){
        this.uploader.removeFile(this.state.file)
        this.setState({
            filename : "",
            status : "",
            progress : 0,
            file : {}
        })
    }

    render(){
        const stopUpload = this.stopUpload.bind(this)
        const startUpload = this.startUpload.bind(this)
        const deleteFile = this.deleteFile.bind(this)

        return (
            <div className="course_video_edit_cr bln">
                <div className="player_cr">
                    <div id="player"><span className="video_loading">播放器加载中</span></div>
                    <div className="op_mask">
                        <div className="op">
                            <div className="hint">
                                <span>{this.state.videoExist ? "点击按钮替换本视频" : "本课程视频尚未上传，点击按钮上传"}</span>
                            </div>
                            <div className="btn btn-primary" id="filePicker">上传</div>
                            {/*{this.state.videoExist ? "替换" : "上传"}*/}
                        </div>
                        <div className="mask"></div>
                    </div>
                </div>
                <div className="upload_progress_lists">
                    <div className="progress_title">
                        <span>上传列表</span>
                    </div>
                    <ul className="upload_ul">
                        <li>
                            <span className="file_name">文件名称</span>
                            <span className="file_status">状态</span>
                            <span className="progress">进度</span>
                            <span className="progress">操作</span>
                        </li>
                        <li>
                            <span className="file_name">{this.state.filename}</span>
                            <span className="file_status">{this.state.status}</span>
                            {this.state.filename == "" || <span className="progress">
                                <div className="progress_bar">
                                    <div className="pr_num">{this.state.progress}%</div>
                                    <div className="process" id="process"></div>
                                    <div className="merge_process" id="merge_process"></div>
                                </div>
                            </span> }
                            {
                                (this.state.filename !== "" &&
                                !(this.state.status === "上传中" || this.state.status === "暂停中" || this.state.status === "合并中") &&
                                this.state.progress !== 100) ?
                                <span className="op">
                                    <div className="btn btn-primary" onClick={startUpload}>开始</div>
                                    <div className="btn btn-danger" onClick={deleteFile}>删除</div>
                                </span> : null
                            }
                                <span className="op">
                                    {this.state.status === "上传中" && <div className="btn btn-danger" onClick={stopUpload}>暂停</div>}
                                    {this.state.status === "暂停中" && <div className="btn btn-primary" onClick={startUpload}>继续</div>}
                                </span>
                        </li>
                    </ul>
                </div>
            </div>
        )
    }
}

export default CourseVideoEdit